package org.ala.tiktools.rpc.kcp.netty.server.config;

import io.netty.channel.*;
import org.ala.tiktools.rpc.kcp.config.RpcKcpConfigInfo;
import org.ala.tiktools.rpc.kcp.netty.IKcpChannelConfig;
import org.ala.tiktools.rpc.kcp.netty.NettyKcp;

import java.util.Map;
import java.util.Objects;

import static org.ala.tiktools.rpc.kcp.netty.KcpChannelOption.*;

/**
 * @author ala
 * @date 2025-04-15 18:14
 */
public class DefaultKcpServerChildChannelConfig extends DefaultChannelConfig implements IKcpChannelConfig {
    /**
     *
     */
    private NettyKcp nettyKcp;
    public DefaultKcpServerChildChannelConfig(Channel channel, NettyKcp kcp) {
        super(channel, new FixedRecvByteBufAllocator(RpcKcpConfigInfo.INSTANCE.getUdpRecvBufferAllocateSize()));
        nettyKcp = Objects.requireNonNull(kcp, "nettyKcp");;
    }


    @Override
    public Map<ChannelOption<?>, Object> getOptions() {
        return getOptions(
                super.getOptions(),
                KCP_NODELAY, KCP_INTERVAL, KCP_FAST_RESEND, KCP_FAST_LIMIT, KCP_NOCWND, KCP_MIN_RTO, KCP_MTU,
                KCP_RCV_WND, KCP_SND_WND, KCP_STREAM, KCP_DEAD_LINK, KCP_AUTO_SET_CONV, KCP_FAST_FLUSH,
                KCP_MERGE_SEGMENT_BUF);
    }

    @Override
    @SuppressWarnings({"unchecked"})
    public <T> T getOption(ChannelOption<T> option) {
        if (option == KCP_NODELAY) {
            return (T) Boolean.valueOf(isNoDelay());
        }
        if (option == KCP_INTERVAL) {
            return (T) Integer.valueOf(getInterval());
        }
        if (option == KCP_FAST_RESEND) {
            return (T) Integer.valueOf(getFastResend());
        }
        if (option == KCP_FAST_LIMIT) {
            return (T) Integer.valueOf(getFastLimit());
        }
        if (option == KCP_NOCWND) {
            return (T) Boolean.valueOf(isNoCwnd());
        }
        if (option == KCP_MIN_RTO) {
            return (T) Integer.valueOf(getMinRto());
        }
        if (option == KCP_MTU) {
            return (T) Integer.valueOf(getMtu());
        }
        if (option == KCP_RCV_WND) {
            return (T) Integer.valueOf(getRcvWnd());
        }
        if (option == KCP_SND_WND) {
            return (T) Integer.valueOf(getSndWnd());
        }
        if (option == KCP_STREAM) {
            return (T) Boolean.valueOf(isStream());
        }
        if (option == KCP_DEAD_LINK) {
            return (T) Integer.valueOf(getDeadLink());
        }
        if (option == KCP_AUTO_SET_CONV) {
            return (T) Boolean.valueOf(isAutoSetConv());
        }
        if (option == KCP_FAST_FLUSH) {
            return (T) Boolean.valueOf(isFastFlush());
        }
        if (option == KCP_MERGE_SEGMENT_BUF) {
            return (T) Boolean.valueOf(isMergeSegmentBuf());
        }
        return super.getOption(option);
    }

    @Override
    public <T> boolean setOption(ChannelOption<T> option, T value) {
        validate(option, value);

        if (option == KCP_NODELAY) {
            setNoDelay((Boolean) value);
        } else if (option == KCP_INTERVAL) {
            setInterval((Integer) value);
        } else if (option == KCP_FAST_RESEND) {
            setFastResend((Integer) value);
        } else if (option == KCP_FAST_LIMIT) {
            setFastLimit((Integer) value);
        } else if (option == KCP_NOCWND) {
            setNoCwnd((Boolean) value);
        } else if (option == KCP_MIN_RTO) {
            setMinRto((Integer) value);
        } else if (option == KCP_MTU) {
            setMtu((Integer) value);
        } else if (option == KCP_RCV_WND) {
            setRcvWnd((Integer) value);
        } else if (option == KCP_SND_WND) {
            setSndWnd((Integer) value);
        } else if (option == KCP_STREAM) {
            setStream((Boolean) value);
        } else if (option == KCP_DEAD_LINK) {
            setDeadLink((Integer) value);
        } else if (option == KCP_AUTO_SET_CONV) {
            setAutoSetConv((Boolean) value);
        } else if (option == KCP_FAST_FLUSH) {
            setFastFlush((Boolean) value);
        } else if (option == KCP_MERGE_SEGMENT_BUF) {
            setMergeSegmentBuf((Boolean) value);
        } else {
            return super.setOption(option, value);
        }

        return true;
    }

    /**
     *  是是否开启Delay
     */
    public boolean isNoDelay() { return nettyKcp.isNoDelay(); }
    public IKcpChannelConfig setNoDelay(boolean noDelay) { nettyKcp.setNodelay(noDelay); return this; }
    /**
     *  刷新间隔
     */
    public int getInterval() { return nettyKcp.getInterval(); }
    public IKcpChannelConfig setInterval(int interval) { nettyKcp.setInterval(interval); return this; }
    /**
     *  几次ack被跳过，快速重试（不用等到reSendTs）
     */
    public int getFastResend() { return nettyKcp.getFastResend(); }
    public IKcpChannelConfig setFastResend(int fastResend) { nettyKcp.setFastResend(fastResend); return this; }
    /**
     *  快速重试最大次数
     */
    public int getFastLimit() { return nettyKcp.getFastLimit(); }
    public IKcpChannelConfig setFastLimit(int limit) { nettyKcp.setFastLimit(limit); return this; }
    /**
     *  是否禁用拥塞窗口
     */
    public boolean isNoCwnd() { return nettyKcp.isNoCwnd(); }
    public IKcpChannelConfig setNoCwnd(boolean cwnd) { nettyKcp.setNocwnd(cwnd); return this; }
    /**
     *  最小rto时间
     */
    public int getMinRto() { return nettyKcp.getMinRto(); }
    public IKcpChannelConfig setMinRto(int minRto) { nettyKcp.setMinRto(minRto); return this; }
    /**
     *  mtu字节数
     */
    public int getMtu() { return nettyKcp.getMtu(); }
    public IKcpChannelConfig setMtu(int mtu) { nettyKcp.setMtu(mtu); return this; }
    /**
     *  rcvWnd大小（单位：消息数）
     */
    public int getRcvWnd() { return nettyKcp.getRcvWnd(); }
    public IKcpChannelConfig setRcvWnd(int rcvWnd) { nettyKcp.setRcvWnd(rcvWnd); return this; }
    /**
     *  sndWnd大小（单位：消息数）
     */
    public int getSndWnd() { return nettyKcp.getSndWnd(); }
    public IKcpChannelConfig setSndWnd(int sndWnd) { nettyKcp.setSndWnd(sndWnd); return this; }
    /**
     *  是否流模式
     */
    public boolean isStream() { return nettyKcp.isStream(); }
    public IKcpChannelConfig setStream(boolean stream) { nettyKcp.setStream(stream); return this; }
    /**
     *  xmit超过该线，kcp状态维置为-1
     */
    public int getDeadLink() { return nettyKcp.getDeadLink(); }
    public IKcpChannelConfig setDeadLink(int deadLink) { nettyKcp.setDeadLink(deadLink); return this; }
    /**
     *  是否自动设置conv
     *  <p> 以第一个收到消息的Conv为准
     */
    public boolean isAutoSetConv() { return nettyKcp.isAutoSetConv(); }
    public IKcpChannelConfig setAutoSetConv(boolean autoSetConv) { nettyKcp.setAutoSetConv(autoSetConv); return this; }
    /**
     *  是否快速flush
     */
    public boolean isFastFlush() { return nettyKcp.isFastFlush(); }
    public IKcpChannelConfig setFastFlush(boolean fastFlush) { nettyKcp.setFastFlush(fastFlush); return this; }
    /**
     *  是否合并Segment
     *  <p> false:每从rcvQue中读到一个消息，触发一次fireChannelRead
     *  <p> true:把一次rcvQue中能读到的消息，合并成一个List，触发一次fireChannelRead
     */
    public boolean isMergeSegmentBuf() { return nettyKcp.isMergeSegmentBuf(); }
    public IKcpChannelConfig setMergeSegmentBuf(boolean mergeSegmentBuf) { nettyKcp.setMergeSegmentBuf(mergeSegmentBuf); return this; }
}
